我覺得這個真是很好的形容
以前還在傳產的時候曾幫公司寫過網頁,處長還我問說是用什麼寫的,我跟他說用javascript
結果他說: 喔喔,Java喔,我以前也學過,不過太難了就放棄
我一直嘗試跟他解釋兩者的差異,但他還是逢人就問會不會Java,能不能幫忙寫網頁
總之兩者是不一樣的東西,大家記住了
一種是在網頁上執行的傳統javascript,作用於前端
另外一種則是在伺服器環境執行的node.js,作用於後端
什麼是前後端?
明確上的定義就是前端是在用戶端執行的,後端則是在伺服端執行的
現在不懂也沒有關係,先往下看吧
今天會先學前端的javascript,不搭配任何框架
框架?
框架就是自動幫你執行某些程式的程序的集合,讓你專注於工作
有點像是車子的引擎,當你在換檔的時候不需要知道哪個齒輪對哪個齒輪,
你只需要知道當你打到幾檔的時候速度多少就可以了
你不用去管他是怎麼做的,你只需要知道他會做就好  
小聲:(其實如果你需要處理很底層的東西的時候還是需要打開框架來看)  
既然框架這麼好,為什麼不要一開始就學框架就好?
因為js有太多框架了,給你們看一張圖就能明白

是不是覺得很可怕?如果你還有興趣可以看這篇
每一個框架都可以當作一個鐵人賽的參賽項目,因此我們先學原生的js吧
由於是要在瀏覽器執行,所以我們先把html寫出來吧
欸?今天怎麼沒有要我們先去下載javascript?
因為javascript已經內嵌在大部分的瀏覽器內了,所以瀏覽器就能執行javascript
可以先打開你的瀏覽器(Chrome,FireFox,Vivaldi都可以)然後按下f12

然後隨便輸入點像樣的程式碼

很酷吧,所以javascript是不用安裝的喔
html有點像是房子的骨架,哪裡有樓梯,電燈的位置,房間的數量等等都是由html指定的
他支撐著整個網頁,告訴你的瀏覽器哪個位置有什麼
現在先在你的工作目錄建立一個副檔名是html的檔案(convert.html之類的)
然後輸入下面的程式碼
<html>
    <head>
        <title>Converter</title>
    </head>
    <body>
        <h1>進制轉換</h1>
        <select id="type">
            <option value="h2t">十六進制轉十進制</option>
            <option value="t2h">十進制轉十六進制</option>
        </select>
        <input type="text" id="input" />
        <input type="button" value="Submit" onclick="convert()" /><br />
        <h3 id="output"></h3>
        <p>Click the "Submit" button and the convert input</p>
    </body>
</html>
接著你可以打開他了,對他點兩下的話應該會用你預設的瀏覽器打開,
如果沒設定的話應該會問你要用哪個程式打開,這時候就選你喜歡的瀏覽器吧
然後你會看到

我們今天主要是學javascript的,所以html的部份我們就快速帶過

<h1>進制轉換</h1>
h1這是標題標籤,用來標記這個文字有多大
你可以把他換成h2~h6並且重新整理網頁看看
<select id="type">
    <option value="h2t">十六進制轉十進制</option>
    <option value="t2h">十進制轉十六進制</option>
</select>
這個是下拉式選單,你可以增加或減少option來看看會發生什麼事
<input type="text" id="input" />
<input type="button" value="Submit" onclick="convert()" /><br />
這兩個雖然都叫input,但是其中一個的type是text,因此他變成了輸入格
另外一個的type是button因此他變成了按鈕
<h3 id="output"></h3>
<p>Click the "Submit" button and the convert input</p>
還記得我前面說h表示標題嗎?這裡代表三級標題,不過現在裡面還沒有東西,因此畫面上沒有顯示
p則是一般的文字,你可以把他前後的標籤都拿掉看看會發生什麼事
因為就如同我說的html就只是房子的骨架,告訴你哪裡有電燈哪裡有房間,
但是如果你需要讓電燈亮起來或是房間的冷氣開始吹,你就需要使用電線把他們接到電源上
這時候就輪到javascript登場了
在html的head裡面加上這些
<head>
    <title>Converter</title>
    <script>
        function convert() {
            input = document.getElementById('input').value;
            type = document.getElementById('type').value;
            switch (type) {
                case 'h2t':
                    document.getElementById('output').innerHTML = h2t(input);
                    break;
                case 't2h':
                    document.getElementById('output').innerHTML = t2h(input);
                    break;
            }
        }
        function t2h(number) {
            for (let i = 0; i < 16; i++) {
                for (let j = 0; j < 16; j++) {
                    for (let k = 0; k < 16; k++) {
                        if (Math.pow(16, 2)*i +Math.pow(16, 1)*j + Math.pow(16, 0)*k == number) {
                            return returnAE(i) + returnAE(j) + returnAE(k);
                        }
                    }
                }
            }
        }
        function returnAE(input) {
            if (input < 10) {
                return input.toString(); //要轉型,不然2056會產生16而非808
            }
            switch (input) {
                case 10:
                    return 'A';
                case 11:
                    return 'B';
                case 12:
                    return 'C';
                case 13:
                    return 'D';
                case 14:
                    return 'E';
                case 15:
                    return 'F';
                default:
                    return 'wrong';
                    break;
            }
        }
        function h2t(number) {
            i = 0;
            output = 0;
            while (i < number.length) {
                output += AEreturn(number[i]) * Math.pow(16, number.length -i -1);
                i++;
            }
            return output;
        }            
        
        function AEreturn(input) {
            switch (input) {
                case 'A':
                    return 10;
                case 'B':
                    return 11;
                case 'C':
                    return 12;
                case 'D':
                    return 13;
                case 'E':
                    return 14;
                case 'F':
                    return 15;
                default:
                    return input;
            }
        }
    </script>
</head>
整個javascript的程式碼會包在
<script></script>
裡面,
javascript的程式碼每一行最後面的;都是可加可不加的,這邊選擇都加
現在先回去看你的body的這一行
<input type="button" value="Submit" onclick="convert()" /><br/>
意思就是如果你沒叫他動,他是不會動的
以往不管是編譯式的C#或是直譯式的python都會有程式開始執行的地方
但是javascript沒有
這裡我們有這一段
onclick="convert()"
意思就是當按下這個按鈕的時候將會執行convert這個函式
(還記得我們剛才說type=button的時候就是按鈕吧)
function convert() {
    input = document.getElementById('input').value;
    type = document.getElementById('type').value;
    switch (type) {
        case 'h2t':
            document.getElementById('output').innerHTML = h2t(input);
            break;
        case 't2h':
            document.getElementById('output').innerHTML = t2h(input);
            break;
    }
}
這個是我們的方法,
由於js跟python一樣都是動態型別,因此不需要定義方法的回傳值跟輸入值的型別
首先我們需要把使用者的輸入值取出來
我們剛才的html已經有指定元件的id了
<select id="type">
    <option value="h2t">十六進制轉十進制</option>
    <option value="t2h">十進制轉十六進制</option>
</select>
<input type="text" id="input" />
看到select跟input了嗎?後面我們指定了id
因此我們只需要把相對應的id給抓出來就可以了
下面就是將相對應id的取出的語法
input = document.getElementById('input').value;
type = document.getElementById('type').value;
我注意到select裡面還有option,他們不用指定id嗎?
不用,因為他是用來描述select這個元件的內容,是屬於select的一部分
反過來說就是取select會取到option的內容,所以你可以不用管他
有看到option的value嗎? 那個就是我們會取到的值,所以我們取值的語法最後面才會加上.value
但是input沒有value欸
因為我們沒有指定預設值,所以他是隱性的(其實存在,但不存在)
你可以把input的內容改成這樣,然後重新整理網頁看看
<input type="text" id="input" value="預設值"/>
switch (type) {
    case 'h2t':
        document.getElementById('output').innerHTML = h2t(input);
        break;
    case 't2h':
        document.getElementById('output').innerHTML = t2h(input);
        break;
}
結構上跟我們在C#還有Java看到得很像,所以就不特別介紹
我們來看output的部份
document.getElementById('output').innerHTML = h2t(input);
這邊我們把執行完程式的結果輸出到id為output的元件中
function t2h(number) {
    for (let i = 0; i < 16; i++) {
        for (let j = 0; j < 16; j++) {
            for (let k = 0; k < 16; k++) {
                if (Math.pow(16, 2)*i +Math.pow(16, 1)*j + Math.pow(16, 0)*k == number) {
                    return returnAE(i) + returnAE(j) + returnAE(k);
                }
            }
        }
    }
}
熟悉的for迴圈及if
等等,好像少了轉型吧?
沒錯,這是由於javascript是弱型別
弱型別就是指如果可行的範圍內,javascript會自動幫轉換型別
你可以在瀏覽器試試下面的行為

注意到
3+"6"
這時候因為字串是可以相加的,因此他會幫你把前面的3轉型成字串
而
6*"6"
由於字串沒有乘法,因此遇到乘法的話反而會把原本是字串的轉型成數字
(其實四則運算只有+會把數字轉成字串)
1=="1" 1==="1" ,又是什麼意思?
===表示嚴格的比較,兩者的型別跟內容必須完全一樣才行
==代表較不嚴格的比較,由於1看起來像"1",因此被判定成跟"1"一樣
(其實裡面的實做是會把其中一個或兩個型別做轉換並且使用===比較)
注意動態型別(例如python)跟弱型別的定義是不一樣的喔
python還是需要轉型來確保型別的正確性,他只是不需要事先指定一個變數的型別而已
蛤,好麻煩喔
這就是為什麼我一開始會先交注重型別的C#的原因,要確保型別的觀念
弱型別的語言將型別的選擇權交在你的手上是因為相信你的程式基本功,比方說下面這一段
function returnAE(input) {
    if (input < 10) {
        return input.toString(); //要轉型,不然2056會產生16而非808
    }
    switch (input) {
        case 10:
            return 'A';
        case 11:
            return 'B';
        case 12:
            return 'C';
        case 13:
            return 'D';
        case 14:
            return 'E';
        case 15:
            return 'F';
        default:
            return 'wrong';
            break;
    }
}
如果你在return的時候沒有轉型,然後又在這一行把回傳值當字串相加
if (Math.pow(16, 2)*i +Math.pow(16, 1)*j + Math.pow(16, 0)*k == number) {
    return returnAE(i) + returnAE(j) + returnAE(k);
}
當今天你的回傳值是8,0,8時,你會得到16,因為+可以同時作用在字串與數字上
這就產生了BUG,也就是程式產生與你期待不符的結果
如果會產生bug那為什麼還要用?
你可以看看下面的程式碼
function h2t(number) {
    i = 0;
    output = 0;
    while (i < number.length) {
        output += AEreturn(number[i]) * Math.pow(16, number.length -i -1);
        i++;
    }
    return output;
}    
        
function AEreturn(input) {
    switch (input) {
        case 'A':
            return 10;
        case 'B':
            return 11;
        case 'C':
            return 12;
        case 'D':
            return 13;
        case 'E':
            return 14;
        case 'F':
            return 15;
        default:
            return input; //其實這裡會回傳字串喔
    }
}
相較於還要轉型的C#,AEreturn在js的寫法是不是簡潔許多?
因為你知道AEreturn出來的值並定會拿去做乘法,而字串是沒有乘法的,因此js會自動幫你轉成數字
現在打開你剛剛寫好的網頁,玩玩看你的程式吧
我們來複習一下吧
js也算是一種大家會推薦給新手學習的語言,畢竟不用安裝就可以直接上了
而且網頁前端一定會用到他(前端條條大路通js)
但網頁實際上要做出東西的話還必須去了解html的語法,然後是css(定義網頁長相的語言,有點像是在你的牆壁上貼好看的壁紙)
接著你會去研究各種框架(Vue,React,Angular...)
然後是各種語法擴充(jQuery,JSX...)
然後是各種開發工具(webpack,Babel...)
而當你總算學完之後可能大家早已遷移到新框架去了
而讓js如此蓬勃發展的原因就是因為有人打開了瀏覽器的大門,
將原本只能在瀏覽器上執行的js變得可以在本地端(也就是你的主機)執行
從此js踏上了統治前後端的道路
於是,明天我們來學node.js吧
如果有任何寫不清楚或是觀念沒有很明白的話請留言告知我
會盡快補上
如果有任何寫錯的地方也麻煩留言告知我
會盡快修正
感謝各位